package com.study.kt._04project.game_tank.model

import com.study.kt._04project.game_tank.Config
import com.study.kt._04project.game_tank.business.*
import com.study.kt._04project.game_tank.enums.Direction
import org.itheima.kotlin.game.core.Composer
import org.itheima.kotlin.game.core.Painter

/**
 * 我方坦克：有运动的能力
 *
 * kotlin特性：接口中声明为val但是实现类中可以声明为var
 *
 * 双方坦克可以互相伤害，所以双方坦克都要具备挨打能力
 */
class Tank(override var x: Int, override var y: Int) : Moveable, Sufferable, Destoryable {


    override var blood: Int = 20

    //宽高
    override var width: Int = Config.block
    override var height: Int = Config.block

    //坦克有方向性，所以需要根据方向绘制(上下左右)
    override var currentDirection: Direction = Direction.UP
    //坦克移动速度
    override var speed: Int = 8

    //记录被阻挡物阻挡，不可以移动的方向
    var badDirection: Direction? = null

    override fun draw() {
        /* when (currentDirection) {
             Direction.UP -> Painter.drawImage("img/tank_u.gif", x, y)
             Direction.DOWN -> Painter.drawImage("img/tank_d.gif", x, y)
             Direction.LEFT -> Painter.drawImage("img/tank_l.gif", x, y)
             Direction.RIGHT -> Painter.drawImage("img/tank_r.gif", x, y)
         }*/

        //when 优化 使用when的返回值
        val img = when (currentDirection) {
            Direction.UP -> "img/tank_u.gif"
            Direction.DOWN -> "img/tank_d.gif"
            Direction.LEFT -> "img/tank_l.gif"
            Direction.RIGHT -> "img/tank_r.gif"
        }
        Painter.drawImage(img, x, y)
    }

    //坦克移动:方向
    fun move(direction: Direction) {

        //如果当前移动方向为不可移动方向直接return
        if (direction == badDirection) {
            return
        }

        //此处业务缺陷：改变方向时，直接朝改变的方向移动了一格，所以需要优化
        //当前方向和希望移动的方向不一致则只改变方向
        if (this.currentDirection != direction) {
            this.currentDirection = direction
            //改变方向后不做移动逻辑
            return
        }

        //改变坦克坐标
        when (currentDirection) {
            //移动的距离为速
            Direction.UP -> y -= speed
            Direction.DOWN -> y += speed
            Direction.LEFT -> x -= speed
            Direction.RIGHT -> x += speed
        }
        //越界处理：防止坦克移动出窗体
        if (x < 0) x = 0
        if (y < 0) y = 0
        if (x > Config.gameWidth - Config.block) x = Config.gameWidth - Config.block
        if (y > Config.gameHeight - Config.block) y = Config.gameHeight - Config.block
    }


    override fun notifyCollisition(blockable: Blockable?, direction: Direction?) {
        //移动到阻挡物在某个方向，则不可以移动
        this.badDirection = direction
    }

    //发射子弹
    fun shoot(): Bullet {
        //使用闭包构造子弹
        return Bullet(this, currentDirection) { bulletWidth, bulletHeight ->
            //坦克位置信息
            val tankX: Int = x
            val tankY: Int = y
            val tankWidth: Int = width
            val tankHeight: Int = height

            //子弹位置信息
            var bulletX = 0
            var bulletY = 0

            //计算字段的坐标，子弹要从坦克的中间发射出来，还有考虑位置因素
            when (currentDirection) {
                Direction.UP -> {
                    //子弹的x值=坦克x坐标+(坦克宽度-子弹宽度)/2
                    //子弹的y值=坦克y坐标-子弹的高度/2
                    //子弹的宽高信息由子弹计算完毕传给外界
                    bulletX = tankX + (tankWidth - bulletWidth) / 2
                    bulletY = tankY - bulletHeight / 2
                }
                Direction.DOWN -> {
                    bulletX = tankX + (tankWidth - bulletWidth) / 2
                    bulletY = tankY + tankHeight - bulletHeight / 2
                }
                Direction.LEFT -> {
                    bulletX = tankX - bulletWidth / 2
                    bulletY = tankY + (tankHeight - bulletHeight) / 2
                }
                Direction.RIGHT -> {
                    bulletX = tankX + (tankWidth - bulletWidth / 2)
                    bulletY = tankY + (tankHeight - bulletHeight) / 2
                }
            }
            Pair(bulletX, bulletY)
        }
    }

    override fun notifySuffer(attachable: Attachable): Array<View>? {
        blood -= attachable.attachPower
        Composer.play("snd/hit.wav")
        return arrayOf(Blast(x, y))
    }

    override fun isDestory(): Boolean = blood <= 0
}